package com.ruoyi.system.service.impl;

import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Sequence;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.google.common.collect.Maps;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.ProjectManagementMapper;
import com.ruoyi.system.service.*;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.google.common.collect.Lists;
import com.ruoyi.common.core.text.Convert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 项目管理Service业务层处理
 *
 * @author zhaonz
 * @date 2023-06-02
 */
@Service
public class ProjectManagementServiceImpl extends MPJBaseServiceImpl<ProjectManagementMapper, ProjectManagement> implements IProjectManagementService {

    private static final Logger logger = LoggerFactory.getLogger(ProjectManagementServiceImpl.class);

    @Autowired
    private IProjectResearchService projectResearchService;

    @Autowired
    private IProjectScheduleService projectScheduleService;

    @Autowired
    private IProjectFileService projectFileService;

    @Autowired
    private IPocTestingService pocTestingService;

    @Autowired
    private IInviteBidsService iInviteBidsService;

    @Resource
    private RuntimeService runtimeService;

    @Resource
    private TaskService taskService;

    @Resource
    private IdentityService identityService;

    @Resource
    private HistoryService historyService;

    /**
     * 查询项目管理列表
     *
     * @param projectManagement 项目管理
     * @return 项目管理
     */
    @Override
    public List<ProjectManagement> list(ProjectManagement projectManagement) {
        MPJLambdaWrapper<ProjectManagement> wrapper = new MPJLambdaWrapper<ProjectManagement>()
                .selectAll(ProjectManagement.class)
                .selectAs(ActRuTask::getId, ProjectManagement::getTaskId)
                .select(ActRuTask::getProcInstId)
                .select(ActRuTask::getAssignee)
                .select(ActRuTask::getName)
                .select(ActRuTask::getFormKey)
                .leftJoin(ActRuExecution.class, ActRuExecution::getBusinessKey, ProjectManagement::getProjectId)
                .leftJoin(ActRuTask.class, ActRuTask::getProcInstId, ActRuExecution::getId)
                .setEntity(projectManagement);
        return this.baseMapper.selectJoinList(ProjectManagement.class, wrapper);
    }

    /**
     * 查询已立项数量
     *
     * @return
     */
    @Override
    public Long selectManagementComplete() {
        return this.baseMapper.selectManagementComplete();
    }

    /**
     * 查询项目管理列表
     *
     * @param projectId 项目管理ID
     * @return 项目管理集合
     */
    @Override
    public ProjectManagement detail(Long projectId) {
        ProjectManagement management = super.getById(projectId);
        if (management.getProjectResearch() == 1) {
            ProjectResearch research = projectResearchService.getOne(new QueryWrapper<ProjectResearch>()
                    .eq("project_id", projectId));
            management.setResearch(research);
        }

        if (management.getPocTesting() == 1) {
            PocTesting testing = pocTestingService.getOne(new QueryWrapper<PocTesting>().eq("project_id", projectId));
            management.setTesting(testing);
        }

        List<ProjectSchedule> schedules = projectScheduleService.list(projectId);
        for (ProjectSchedule schedule : schedules) {
            if (schedule.getIsWithFiles() == 1) {
                List<ProjectFile> projectFiles = projectFileService.list(new QueryWrapper<ProjectFile>().eq("project_id", projectId)
                        .eq("schedule_id", schedule.getScheduleId()));
                schedule.setProjectFiles(projectFiles);
            }

            if ("INVITE_BIDS".equals(schedule.getProjectSchedule())){
                management.setInviteBids(iInviteBidsService.getOne(new QueryWrapper<InviteBids>().eq("project_id", projectId)));
            }
        }

        management.setSchedule(schedules);

        return management;
    }


    /**
     * 批量删除项目管理
     *
     * @param projectIds 需要删除的项目管理主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int removeByIds(String projectIds) {
        List<String> list = Lists.newArrayList(Convert.toStrArray(projectIds));
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String projectId = iterator.next();
            ProjectManagement management = this.list(new ProjectManagement().setProjectId(Long.parseLong(projectId))).get(0);
            if (management.getProjectResearch() == 1) {
                projectResearchService.remove(new QueryWrapper<ProjectResearch>()
                        .eq("project_id", management.getProjectId()));
            }

            if (management.getPocTesting() == 1) {
                pocTestingService.remove(new QueryWrapper<PocTesting>()
                        .eq("project_id", management.getProjectId()));
            }

            List<ProjectSchedule> projectSchedules = projectScheduleService.list(new QueryWrapper<ProjectSchedule>()
                    .eq("project_id", management.getProjectId()));
            for (ProjectSchedule projectSchedule : projectSchedules) {
                if (projectSchedule.getIsWithFiles() == 1){
                    projectFileService.remove(new QueryWrapper<ProjectFile>()
                            .eq("project_id", management.getProjectId())
                            .eq("schedule_id", projectSchedule.getScheduleId()));
                }
                projectScheduleService.removeById(projectSchedule.getScheduleId());
            }

            if (!"END".equals(management.getProjectSchedule()) && management.getTaskId() != null) {
                Task t = taskService.createTaskQuery().taskId(management.getTaskId()).singleResult();
                runtimeService.deleteProcessInstance(t.getProcessInstanceId(), "强制结束");
            }
        }

        return this.baseMapper.deleteBatchIds(list);
    }

    /**
     * 保存项目管理
     *
     * @param projectManagement 项目管理
     * @return 结果
     */
    @Override
    public boolean save(ProjectManagement projectManagement) {
        Sequence sequence = new Sequence(1, 1);
        projectManagement.setProjectId(sequence.nextId());
        projectManagement.setCreateTime(DateUtils.getNowDate());
        boolean save = super.save(projectManagement);
        if (save) {
            // 发起项目流程
            identityService.setAuthenticatedUserId(projectManagement.getCreateBy());
            Map<String, Object> variables = Maps.newHashMap();
            variables.put("createBy", projectManagement.getCreateBy());
            variables.put("projectId", projectManagement.getProjectId());
            runtimeService.startProcessInstanceByKey("management",
                    String.valueOf(projectManagement.getProjectId()),
                    variables);
        }
        return save;
    }

}
